/*
 *	Copyright (C) 2008 CRIMERE
 *	Copyright (C) 2008 Jean-Marc Mercier
 *	
 *	This file is part of OTS (optimally transported schemes), an open-source library
 *	dedicated to scientific computing. http://code.google.com/p/optimally-transported-schemes/
 *
 *	CRIMERE makes no representations about the suitability of this
 *	software for any purpose. It is provided "as is" without express or
 *	implied warranty.
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 */
#if !defined _analyzer_memory_leak_
#define _analyzer_memory_leak_
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
#include <map>
#include <set>
#include <string>
#include <src/miscellaneous/OS_basic.h>
#include <src/miscellaneous/stat/Analyzer_Performance.h>
#include <iostream>

struct Analyzer_Memory_Cell : public Common_Cell<int> {
		typedef int cell_parameter_type;
		typedef Common_Cell<int> Base;
		Analyzer_Memory_Cell() : memory_(0) {};
		Analyzer_Memory_Cell(const std::string & name) : memory_(0), Base(name) {};
		virtual ~Analyzer_Memory_Cell(){};
		virtual int operator()() const {return memory_;};
		void operator()(const cell_parameter_type& memory) {
			memory_+=memory;
			count_++;
		};
		cell_parameter_type memory_;
	};

std::ostream &operator<<(std::ostream &out, const Analyzer_Memory_Cell &v);

class Analyzer_Memory : public Analyzer_Common<Analyzer_Memory,Analyzer_Memory_Cell >{
	public :
		typedef Analyzer_Common<Analyzer_Memory,Analyzer_Memory_Cell > Base;
		Analyzer_Memory(const std::string & name) : Base(name) {
			_CrtMemCheckpoint(&memory_);
		};
		virtual ~Analyzer_Memory(){ end (); };
		virtual void begin() {
			_CrtMemCheckpoint(&memory_);
		};
		virtual void end() {
			_CrtMemState memory_now;
			_CrtMemCheckpoint(&memory_now);
			_CrtMemState p3;
			cell_parameter_type count=0;
			if ( _CrtMemDifference( &p3, &memory_, &memory_now) ) {
				for (std::size_t i = 0;i <_MAX_BLOCKS; i ++)
					count += p3.lSizes[i];
			};
			finish(count);
			_CrtMemCheckpoint(&memory_);
		};
		_CrtMemState memory_;
	};


#endif